package cn.eoeit.mmy.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Base64;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;


public class SysUtils {

	/**
	 * 将json字符串转换成java对象
	 * 
	 * @param json
	 * @param object
	 * @return
	 */
	public static Object parseJSONStringToObject(String json, Object object) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			return mapper.readValue(json, object.getClass());
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将json字符串转换成List
	 * 
	 * @param json
	 * @param object
	 * @return
	 */
	public static List<?> parseJSONStringToList(String json, Class<?> object) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			return mapper.readValue(json, mapper.getTypeFactory().constructParametricType(List.class, object));
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将java对象转换成json字符串
	 * 
	 * @param object
	 * @return
	 */
	public static String parseObjectToJSONString(Object object) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			return mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 截取字符串的前limit个字符
	 *
	 * @param string
	 *            原字符串
	 * @param limit
	 *            截取长度
	 * @return String
	 */
	public static String substring(String string, int limit) {
		StringBuffer returnString = new StringBuffer();
		if (string == null || limit <= 0 || limit > string.length()) {
			return string;
		}
		char[] temp = string.toCharArray();
		for (int i = 0; i < limit; i++) {
			returnString.append(temp[i]);
		}
		return returnString.toString();
	}

	/**
	 * 随机产生N位验证码
	 * 
	 * @return
	 */
	public static char[] getRandNum(int n) {
		char[] rand = new char[n];
		String str = "23456789qwertyuipkjhgfdsacvbnmQWERTYUPLKJHGFDSACVBNM";
		for (int i = 0; i < n; i++) {
			Random rd = new Random();
			int index = rd.nextInt(str.length());

			// 通过下标获取字符
			rand[i] = str.charAt(index);
		}
		return rand;
	}

	/**
	 * 随机产生N位验证码
	 * 
	 * @return 字符串
	 */
	public static String getRandCharString(int n) {
		char[] rand = new char[n];
		String str = "23456789qwertyuipkjhgfdsacvbnmQWERTYUPLKJHGFDSACVBNM";
		for (int i = 0; i < n; i++) {
			int index = new Random().nextInt(str.length());
			rand[i] = str.charAt(index); // 通过下标获取字符
		}
		return String.valueOf(rand);
	}
	
	/**
	 * 随机产生N位验证码
	 * 
	 * @return 字符串
	 */
	public static Integer getRandNumber(int n) {
		char[] rand = new char[n];
		String str = "1234567809";
		for (int i = 0; i < n; i++) {
			int index = new Random().nextInt(str.length());
			rand[i] = str.charAt(index); // 通过下标获取字符
		}
		return Integer.parseInt(String.valueOf(rand));
	}

	/**
	 * 生成图片 - 验证码
	 * 
	 * @param randNum
	 *            验证码
	 * @return
	 */
	public static BufferedImage generateRandImg(char[] randNum) {

		// 在内存中创建图象
		int width = 162, height = 45;

		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		// 获取图形上下文
		Graphics g = image.getGraphics();

		// 生成随机类
		Random random = new Random();

		// 设定背景色
		g.setColor(getRandColor(200, 250));

		g.fillRect(0, 0, width, height);

		// 设定字体
		g.setFont(new Font("Times New Roman", Font.PLAIN, 28));

		// 画边框
		// g.setColor(new Color());
		// g.drawRect(0,0,width-1,height-1);

		// 随机产生160条干扰线，使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < 160; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(12);
			int yl = random.nextInt(12);
			g.drawLine(x, y, x + xl, y + yl);
		}

		String strRandNum = "";
		for (int i = 0; i < 4; i++) {// 取出验证码(4位数字)
			strRandNum = Character.toString(randNum[i]);
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			g.drawString(strRandNum, 38 * i + 6, 28);// 将验证码显示到图象中
		}

		// 图象生效
		g.dispose();

		return image;
	}

	/**
	 * 获得随机图片颜色
	 * 
	 * @param fc
	 * @param bc
	 * @return
	 */
	private static Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255) {
			fc = 255;
		}
		if (bc > 255) {
			bc = 255;
		}
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

	/**
	 * 生成订单 author jwb
	 * 
	 * @param type
	 *            1.用户订购 2 用户租赁 3 合作伙伴代购 4 合作伙伴代租赁 5 合作伙伴批购6表示 代理商升级订单
	 * @return
	 */
	public static String getOrderNum(int type) {
		SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMddHHmmssSSS");
		return type + sdf.format(new Date());
	}

	/**
	 * author jwb
	 * 
	 * @param arry
	 * @return
	 */
	public static String Arry2Str(int[] arry) {
		StringBuilder sb = new StringBuilder();
		if (arry != null && arry.length > 0) {
			sb.append("(");
			for (Object object : arry) {
				sb.append(object + ",");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
		}
		return sb.toString();
	}

	public static String Arry2Str(List<Integer> arry) {
		StringBuilder sb = new StringBuilder();
		if (arry != null && arry.size() > 0) {
			sb.append("(");
			for (Object object : arry) {
				sb.append(object + ",");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
		}
		return sb.toString();
	}

	/**
	 * author jwb
	 * 
	 * @param arry
	 * @return
	 */
	public static String Arry2Str(String[] arry) {
		StringBuilder sb = new StringBuilder();
		if (arry != null && arry.length > 0) {
			sb.append("(");
			for (String a : arry) {
				sb.append("'" + a + "',");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append(")");
		}
		return sb.toString();
	}

	/**
	 * author jwb
	 * 
	 * @param s
	 * @return
	 */
	public static int Object2int(Object o) {
		if(o ==null){
			return 0;
		}else if(o instanceof Integer){
           return (Integer)o;
		}
		try {
			return Integer.valueOf(o.toString().trim());
		} catch (Exception e) {
			return 0;
		}
	}

	/**
	 * 加密
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public static String Encryption(String passwors, String path) throws Exception {
		String[] arstr = findPasswprdPath(path);
		String ret = null;
		Key keySpec = new SecretKeySpec(arstr[0].getBytes(), "AES"); // 两个参数，第一个为私钥字节数组，
																		// 第二个为加密方式
																		// AES或者DES
		IvParameterSpec ivSpec = new IvParameterSpec(arstr[1].getBytes());
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 实例化加密类，参数为加密方式，要写全
		cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
		byte[] b = cipher.doFinal(passwors.getBytes());// 加密操作,返回加密后的字节数组，然后需要编码。主要编解码方式有Base64,
														// HEX,
														// UUE,7bit等等。此处看服务器需要什么编码方式
		ret = Base64.encodeBase64String(b);
		return ret;
	}

	/**
	 * 解密
	 * 
	 * @param password
	 * @return
	 * @throws FileNotFoundException
	 * @throws NoSuchPaddingException
	 * @throws NoSuchAlgorithmException
	 */
	public static String Decrypt(String password, String path) throws Exception {
		String[] arstr = findPasswprdPath(path);
		String str = null;
		byte[] passByte = Base64.decodeBase64(password); // 先用Base64解码
		IvParameterSpec ivSpec = new IvParameterSpec(arstr[1].getBytes());
		Key key = new SecretKeySpec(arstr[0].getBytes(), "AES");
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);// 与加密时不同MODE:Cipher.DECRYPT_MODE
		byte[] ret = cipher.doFinal(passByte);
		str = new String(ret, "utf-8");
		return str;
	}

	/**
	 * 获得秘钥
	 * 
	 * @param path
	 * @throws FileNotFoundException
	 */
	@SuppressWarnings("resource")
	public static String[] findPasswprdPath(String path) throws FileNotFoundException {
		File file = new File(path);
		Scanner in = null;
		String result = "";
		in = new Scanner(file);
		while (in.hasNextLine()) {
			result += in.nextLine() + ",";
		}
		String[] ar = result.split(",");
		return ar;
	}

	/***
	 * MD5加码 生成32位md5码
	 */
	public static String string2MD5(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			System.out.println(e.toString());
			e.printStackTrace();
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();

	}

	
	
	/**
	 * 获取随机的6位数字验证码
	 * @return
	 */
	public static String getCode() {
		char[] randomChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
		Random random = new Random();
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < 6; i++) {
			stringBuffer.append(randomChar[Math.abs(random.nextInt()) % randomChar.length]);
		}
		String mobilecode = stringBuffer.toString();
		return mobilecode;
	}


	/**
	 * 验证手机号码
	 * 
	 * @param mobiles
	 * @return
	 */
	public static boolean isMobileNO(String mobiles) {
		boolean flag = false;
		try {
			Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
			Matcher m = p.matcher(mobiles);
			flag = m.matches();
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}

	/**
	 * string转****
	 * 
	 * @param string
	 * @return
	 */
	public static String toProSub2(String s) {
		String ss[] = s.split("@");
		if (ss.length == 1) {
			int a = s.length() / 3;
			String s2 = s.substring(0, a);
			String s3 = s.substring(s.length() - a, s.length());
			return s2 + "****" + s3;
		} else {
			String s1 = "";
			if (ss[0].length() == 1) {
				s1 = "*";
			} else if (ss[0].length() == 2) {
				s1 = "**";
			} else if (ss[0].length() == 3) {
				s1 = "***";
			} else if (ss[0].length() == 4) {
				s1 = "****";
			} else {
				s1 = ss[0].substring(0, ss[0].length() - 4) + "****";
			}
			return s1 + "@" + ss[1];
		}
	}

	public static String[] list2Arr(List<Integer> list) {
		if (list != null && !list.isEmpty()) {
			String[] arr = new String[list.size()];
			for (int i = 0, j = list.size(); i < j; i++) {
				arr[i] = String.valueOf(list.get(i));
			}
			return arr;
		}
		return null;
	}
	
	/**
	 * 获取客户端IP
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {   
		String ipAddress = null;   
		//ipAddress = request.getRemoteAddr();   
		ipAddress = request.getHeader("x-forwarded-for");   
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {   
			ipAddress = request.getHeader("Proxy-Client-IP");   
		}   
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {   
			ipAddress = request.getHeader("WL-Proxy-Client-IP");   
		}   
		if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {   
			ipAddress = request.getRemoteAddr();   
			if(ipAddress.equals("127.0.0.1")){   
				//根据网卡取本机配置的IP   
				InetAddress inet=null;   
				try {   
					inet = InetAddress.getLocalHost();   
				} catch (UnknownHostException e) {   
					e.printStackTrace();   
				}   
				ipAddress= inet.getHostAddress();   
			}   
		}   

		//对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割   
		if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15   
			if(ipAddress.indexOf(",")>0){   
				ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));   
			}   
		}   
		return ipAddress;    
	} 
	
	public static String formatDate(String format) {
		   SimpleDateFormat sdformat = new SimpleDateFormat(format);
	       return sdformat.format(new Date());   
	}

	public static String getCurrentMonthStart() {
		 SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM");
	      String  date= sdformat.format(new Date());   
		return date+"-01";
	}

	public static String formatAgentCode(String code) {
		String str = String.valueOf(Integer
				.parseInt(code) + 1);
		if (str.length()%3 == 1) {
			str = "00" + str;
		}
		if (str.length()%3 == 2) {
			str = "0" + str;
		}
		return str;
	}

	/**
	 * 
	 * @param amount
	 * @param pointLength
	 * @return
	 */
	public static String formatNumber(double amount, int pointLength) {
		BigDecimal   b   =   new   BigDecimal(amount);  
		BigDecimal result= b.setScale(pointLength,   BigDecimal.ROUND_HALF_UP);
		return result.toPlainString();
	} 
	
	public static String formatDate(Date date,String format) {
		   SimpleDateFormat sdformat = new SimpleDateFormat(format);
	       return sdformat.format(date);   
	}

	
	
	public static Date parseDate(String date,String format){
		 SimpleDateFormat sdformat = new SimpleDateFormat(format);
		 try {
			return  sdformat.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return  null;
		}
	}

	/**
	 * 代理商等级购买 下月生效
	 * @param createAt
	 * @return
	 */
	public static Date getAgentLevelEffectDate(Date createAt) {
		 Calendar cal = Calendar.getInstance();
		 cal.setTime(createAt);
		 cal.add(Calendar.MONTH, 1);
		 cal.set(Calendar.DAY_OF_MONTH, 1);
		 cal.set(Calendar.HOUR_OF_DAY, 0);
		 cal.set(Calendar.MINUTE, 0);
		 cal.set(Calendar.SECOND, 0);
		return cal.getTime();
	}

	public static String formatPhoneNum(String sphone) {
		if (sphone != "") {
			int a = sphone.length() / 3;
			String s2 = sphone.substring(0, a);
			String s3 = sphone.substring(sphone.length() - a, sphone.length());
			sphone = s2 + "****" + s3;
		}
		return sphone;
	}

	//银行卡号格式化
		public static String formatMaskPan(String payFromAccount) {
			if(payFromAccount==null||payFromAccount.length()<10){
				return payFromAccount;
			}
			int length=payFromAccount.length();
			StringBuffer buffer=new StringBuffer();
			if(length>10){
				buffer.append(payFromAccount.substring(0,6));
				for(int i=6;i<length-4;i++){
					buffer.append("*");
				}
				buffer.append(payFromAccount.substring(length-4));
			}
			return buffer.toString();
		} 
	

		 /**
		 * 计算2个日期相隔天数
		 * 
		 * @param start
		 *            开始时间
		 * @param end
		 *            结束时间
		 * @return
		 */
	    public static int getDaysApart(Date start, Date end) {
			return (int) (end.getTime() - start.getTime()) / (1000 * 3600 * 24);
		}

		/**
		 * 计算2个日期相隔月数
		 * 
		 * @param start
		 *            开始时间
		 * @param end
		 *            结束时间
		 * @param isExtend
		 *            不足一个月的是否要补足一个月
		 * @return
		 */
	    public static int getMonthsApart(Date start, Date end, boolean isExtend) {
			Calendar calendar = Calendar.getInstance();

			calendar.setTime(start);
			int yearStart = calendar.get(Calendar.YEAR);
			int monthStart = calendar.get(Calendar.MONTH);
			int dayStart = calendar.get(Calendar.DAY_OF_MONTH);

			calendar.setTime(end);
			int yearEnd = calendar.get(Calendar.YEAR);
			int monthEnd = calendar.get(Calendar.MONTH);
			int dayEnd = calendar.get(Calendar.DAY_OF_MONTH);

			int months = (yearEnd - yearStart) * 12 + (monthEnd - monthStart);
			if (isExtend && dayStart > dayEnd) {
				return months + 1;
			}
			return months;
		}

		/**
		 * 按月划分区间
		 * 
		 * @param start
		 * @param end
		 * @return
		 */
	    public static Date[][] divide2Months(Date start, Date end) {
			int monthsApart = getMonthsApart(start, end, false);
			Date[][] dates = new Date[monthsApart + 1][2];

			// 获取开始时间所在月的第一天
			Calendar min = Calendar.getInstance();
			min.setTime(start);
			min.set(Calendar.DAY_OF_MONTH,
					min.getActualMinimum(Calendar.DAY_OF_MONTH));

			// 获取结束时间所在月的最后一天
			Calendar max = Calendar.getInstance();
			max.setTime(end);
			max.set(Calendar.DAY_OF_MONTH,
					min.getActualMaximum(Calendar.DAY_OF_MONTH));

			Calendar curr = min;
			int index = 0;
			while (curr.before(max)) {
				if(index>=monthsApart + 1){
					return dates;
				}
				curr.set(Calendar.DAY_OF_MONTH,
						min.getActualMaximum(Calendar.DAY_OF_MONTH));
				Date currEnd = curr.getTime();
				curr.set(Calendar.DAY_OF_MONTH,
						min.getActualMinimum(Calendar.DAY_OF_MONTH));
				Date currStart = curr.getTime();
				dates[index][0] = currStart;
				dates[index][1] = currEnd;
				curr.add(Calendar.MONTH, 1);
				index++;
			}
			return dates;
		}

     

		public static String getLastMonthDay(String month) {
		    SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM");
		    try {
				
				
				String currentMonth=dateFormat.format(new Date());
				if(currentMonth.equals(month)){
					SimpleDateFormat dateFormat2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					return dateFormat2.format(new Date());
				}else{
					Date date=dateFormat.parse(month);
					Calendar calendar=Calendar.getInstance();
					calendar.setTime(date);
					int maxDay=calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
					return month+"-"+maxDay+" 23:59:59";
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		    return month+"-31 23:59:59";
		}

		public static String arr2Spl(String[] arr) {
			String a = "";
			String b = "";
			if(arr.length>0){
				for(int i=0 ; i<arr.length ; i++){
					a+=("'"+arr[i].trim()+"'"+",");
				}
			}
			b=a.substring(0,a.length()-1);
			return b;
		}
		
		public static String arrayToDelimitedString(Object[] arr, String delim) {
			if (arr == null || arr.length == 0) {
				return "";
			}
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < arr.length; i++) {
				if (i > 0) {
					sb.append(delim);
				}
				sb.append(arr[i]);
			}
			return sb.toString();
		}

		
		/**
		 * 保存图片并返回保存路径
		 * @return 
		 * 
		 * */
		public static String upload(MultipartFile file,HttpServletRequest request) {
			String path = request.getSession().getServletContext().getRealPath("upload/logo");  
	        String fileName = file.getOriginalFilename();  
	        File targetFile = new File(path, fileName);  
	        
	        if(!targetFile.exists()){  
	            targetFile.mkdirs();  
	        }  
	  
	        //保存  
	        try {  
	            file.transferTo(targetFile);  
	            return "/upload/logo/"+fileName;
	        } catch (Exception e) {  
	            e.printStackTrace();  
	            return null;
	        }  
		}

	
}